from catmaConfig import ATTRIB_FLAGS, TYPEID_NONE
import stims
import catmaDB
DEBUG = False

def CreateAdapter(typeName, db):
    adapterType = db.GetType(typeName)
    values = adapterType.GetAllValues(ATTRIB_FLAGS.MODULIZED)
    fittingInfo = GetSlotAttributeValuesAll(typeName, 'slotType', db)
    adapter = stims.Adapter(typeName, fittingInfo, values)
    return adapter



def GetSlotAttributeValuesAll(typeName, slotAttributeName, db):
    adapterType = db.GetType(typeName)
    attributesInfo = []
    try:
        slots = adapterType.GetValue('mSlots')
        slots.CacheInheritedValues()
        slotNames = slots.GetValueNames()
        slotNames.sort()
        for slotName in slotNames:
            slotInfo = slots.GetValue(slotName)
            slotCount = slotInfo.GetValue('count')
            try:
                attrValue = slotInfo.GetValue(slotAttributeName)
                if (attrValue == ''):
                    attrValue = None
            except catmaDB.CatmaDBError, e:
                attrValue = None
                if DEBUG:
                    print 'exception when creating adapter: ',
                    print e
            attributesInfo += ([attrValue] * slotCount)

    except catmaDB.CatmaDBError, e:
        if DEBUG:
            print 'exception when creating adapter: ',
            print e
    try:
        slots = adapterType.GetValue('mAssociatedSlots')
        slots.CacheInheritedValues()
        slotNames = slots.GetValueNames()
        slotNames.sort()
        for slotName in slotNames:
            slotInfo = slots.GetValue(slotName)
            try:
                attrValue = slotInfo.GetValue(slotAttributeName)
                if (attrValue == ''):
                    attrValue = None
            except catmaDB.CatmaDBError, e:
                attrValue = None
                if DEBUG:
                    print 'exception when creating adapter: ',
                    print e
            attributesInfo += [attrValue]

    except catmaDB.CatmaDBError, e:
        if DEBUG:
            print 'exception when creating adapter: ',
            print e
    return attributesInfo



def GetAllSpawnedAdapterModuleType(adapterTypeID):
    db = catmaDB.GetDB()
    spawnedModuleTypes = []
    adapterType = db.GetTypeByID(adapterTypeID)
    try:
        slots = adapterType.GetValue('mAssociatedSlots')
        slots.CacheInheritedValues()
        slotNames = slots.GetValueNames()
        slotNames.sort()
        for slotName in slotNames:
            slotInfo = slots.GetValue(slotName)
            try:
                moduleTypeID = slotInfo.GetValue('defaultModuleType')
                if (moduleTypeID == TYPEID_NONE):
                    moduleTypeID = None
            except CatmaDBError, e:
                moduleTypeID = None
                if DEBUG:
                    print 'exception when creating adapter: ',
                    print e
            if (moduleTypeID and ((moduleTypeID not in spawnedModuleTypes) and (db.GetValueByTypeID(moduleTypeID, 'moduleType') == 'MT_Spawn'))):
                spawnedModuleTypes.append(moduleTypeID)

    except CatmaDBError, e:
        if DEBUG:
            print 'exception when creating adapter: ',
            print e
    return spawnedModuleTypes



def GetSlotAttributeValue(typeName, slotIndex, slotAttributeName, db):
    allValues = GetSlotAttributeValuesAll(typeName, slotAttributeName, db)
    if (slotIndex >= len(allValues)):
        return 
    else:
        return allValues[slotIndex]



def CreateModule(typeID, db):
    moduleType = db.GetTypeByID(typeID)
    slotType = moduleType.GetValue('slotType')
    isPassive = moduleType.GetValue('isPassive')
    duration = moduleType.GetValue('duration')
    rechargeTime = moduleType.GetValue('rechargeTime')
    cycles = moduleType.GetValue('cycles')
    activationTime = moduleType.GetValue('activationTime')
    parameters = {}
    parameters['typeID'] = typeID
    parameters['slotType'] = slotType
    parameters['isPassive'] = isPassive
    parameters['duration'] = duration
    parameters['rechargeTime'] = rechargeTime
    parameters['cycles'] = cycles
    parameters['activationTime'] = activationTime
    modifierAttributes = []
    try:
        modifiers = moduleType.GetValue('modifier')
        modifiers.CacheInheritedValues()
        for elementName in modifiers.GetValueNames():
            elem = modifiers.GetValue(elementName)
            attType = elem.GetValue('attributeType')
            attName = elem.GetValue('attributeName')
            modifierType = elem.GetValue('modifierType')
            modifierValue = elem.GetValue('modifierValue')
            modifierAttributes.append((attType,
             attName,
             modifierType,
             modifierValue))

    except catmaDB.CatmaDBError, e:
        print 'got CatmaDBError when getting modifier info on module:',
        print e
    function = (stims.MOD_PASSIVE if isPassive else stims.MOD_ACTIVE)
    parameters['function'] = function
    module = stims.Module(parameters, modifierAttributes)
    return module



def ApplyDefaultFitting(db, adapter):
    defaultModuleList = GetSlotAttributeValuesAll(adapter.typeName, 'defaultModuleType', db)
    slotIndex = 0
    for moduleTypeID in defaultModuleList:
        if (moduleTypeID and (moduleTypeID != TYPEID_NONE)):
            newModule = CreateModule(moduleTypeID, db)
            adapter.FitModule(newModule, slotIndex)
        slotIndex = (slotIndex + 1)




def ApplyFitting(db, adapter, moduleList, autoFitting = False):
    if autoFitting:
        modules = []
        for moduleTypeID in moduleList:
            if moduleTypeID:
                modules.append(CreateModule(moduleTypeID, db))

        adapter.AutoFitModules(modules)
        return 
    if (len(moduleList) != len(adapter.slots)):
        raise RuntimeError(("ApplyFitting: Entries in 'moduleList' <%s> doesn't match number of slots on the adapter <%s>." % (moduleList, len(adapter.slots))))
    operations = []
    for (i, moduleTypeID,) in enumerate(moduleList):
        (slotType, module,) = adapter.slots[i]
        if (moduleTypeID is None):
            if module:
                operations.append((None, i))
        else:
            if ((module is None) or (module.typeID != moduleTypeID)):
                newModule = CreateModule(moduleTypeID, db)
                operations.append((newModule, i))

    adapter.FitModules(operations)



def GetModulePGCPUInfo(db, moduleTypeID):
    moduleType = db.GetTypeByID(moduleTypeID)
    powerUsage = 0
    cpuUsage = 0
    try:
        modifiers = moduleType.GetValue('modifier')
        modifiers.CacheInheritedValues()
        for elementName in modifiers.GetValueNames():
            elem = modifiers.GetValue(elementName)
            attName = elem.GetValue('attributeName')
            modifierType = elem.GetValue('modifierType')
            modifierValue = elem.GetValue('modifierValue')
            if (modifierType == 'ADD'):
                if (attName == 'mVICProp.maxCpuReserve'):
                    cpuUsage += -modifierValue
                else:
                    if (attName == 'mVICProp.maxPowerReserve'):
                        powerUsage += -modifierValue

    except catmaDB.CatmaDBError, e:
        pass
    return (powerUsage, cpuUsage)



